﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


using STSdb.MTL.Utils.Async;

namespace STSdb.MTL
{
    /// <summary>
    /// Object accessed by user via STSdbMTLEngine instance
    /// </summary>
    public class Scheme
    {
        TransactionsCoordinator _transactionsCoordinator = null;

        public Scheme(TransactionsCoordinator transactionsCoordinator)
        {
            this._transactionsCoordinator = transactionsCoordinator;
        }

        /// <summary>
        /// Gives ability to set up existing tables properties, which will be applied on the fly, after engine instantiation.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="T1"></typeparam>
        /// <param name="tableName"></param>
        /// <param name="tableProperties"></param>
        public void SetTableProperties<T,T1>(string tableName, TableProperties<T,T1> tableProperties)
        {            
            this._transactionsCoordinator.TablesCoordinator.SetTableProperties<T, T1>(tableName, tableProperties);
        }


        /// <summary>
        /// Returns true if table exists. Also can be accessed via transaction.
        /// </summary>
        /// <param name="tableName"></param>
        /// <returns></returns>
        public bool IF_TableExists(string tableName)
        {
            //COMPACTED TABLE NAMES ARE CORRECTED

            return this._transactionsCoordinator.SchemaCoordinator.IF_TableExists(tableName);
        }

        /// <summary>
        /// Deletes table from the schema and internal structures. Also can be accessed via transaction.
        /// </summary>
        /// <param name="tableName"></param>
        public void DeleteTable(string tableName, bool deleteAlsoRawFile)
        {
            if (deleteAlsoRawFile)
            {
                this._transactionsCoordinator.SchemaCoordinator.DeleteTableWithRawFile(tableName, deleteAlsoRawFile);
            }
            else
            {
                this._transactionsCoordinator.SchemaCoordinator.DeleteTable(tableName);
            }           
        }

        /// <summary>
        /// Deletes tables from the schema and internal structures. Also can be accessed via transaction.
        /// </summary>
        /// <param name="tableNames"></param>
        public void DeleteTables(List<string> tableNames, bool deleteAlsoRawFile)
        {
            if (deleteAlsoRawFile)
            {
                tableNames
                 .ForEach
                 (r =>
                     this._transactionsCoordinator.SchemaCoordinator.DeleteTableWithRawFile(r, deleteAlsoRawFile)
                 );
            }
            else
            {
                tableNames
                 .ForEach
                 (r =>
                     this._transactionsCoordinator.SchemaCoordinator.DeleteTable(r)
                 );
            }         
        }

        /// <summary>
        /// Returns list of all tables names inside of the database.  Also can be accessed via transaction.
        /// </summary>
        /// <returns></returns>
        public List<string> GetAllTablesNames()
        {
            //COMPACTED TABLE NAMES ARE CORRECTED
            return this._transactionsCoordinator.SchemaCoordinator.GetAllTablesNames();
        }

        ///// <summary>
        ///// IN DEV. NOT FOR USAGE.
        ///// Returns TableInformation.
        ///// If table doesn't exist returns null
        ///// </summary>
        ///// <param name="tableName"></param>
        //public TableInformation GetTableInformation(string tableName)
        //{
        //    return this._transactionsCoordinator.SchemaCoordinator.GetTableInformation(tableName);
        //}


        ///////// <summary>
        ///////// IN DEV. NOT FOR USAGE. AND WILL BE NOT FOR USAGE, ONLY AUTO-COMPACTING WILL BE POSSIBLE.
        ///////// Asynchronously calls Table Exhale method. Giving ability to the table to recompact self and to free previously allocated space by the old instance.
        ///////// Freed space will be used by VFS for storing new tables and portions of data. This process is called DataBreezing. 
        ///////// We can achive it thanks to the small storage size of STS sorted data and blazing fast insert speed.
        ///////// This function can be called manually, but also will be called automatically if wasted space will be above 20% and bigger then 1 sector size or 1 MB...has to be tested.
        ///////// </summary>
        ///////// <param name="tableName"></param>
        //////public TableCompactingResult Exhale(string tableName)
        //////{

        //////    //TEMP NOT ASYNC
        //////    return this._transactionsCoordinator.SchemaCoordinator.StsTablesSchema.CompactTable(tableName);

            

        //////    Action a = () =>
        //////        {
        //////            this._transactionsCoordinator.SchemaCoordinator.StsTablesSchema.CompactTable(tableName);
        //////        };

        //////    a.DoAsync();

        //////    return new TableCompactingResult();
        //////}

        /// <summary>
        /// Returns table definitions
        /// </summary>
        /// <param name="tableName"></param>
        /// <returns></returns>
        public List<string> GetTableDefinition(string tableName)
        {
            return this._transactionsCoordinator.SchemaCoordinator.GetTableDefinition(tableName);
        }
    }
}
